/**
 * Client
 * 
 * 29/12/2013
 * 
 * Copyright GPL
 */
package com.jtmproject.bluetooth;

import com.jtmproject.IClient;
import com.jtmproject.PongGame;
import com.jtmproject.World;
import com.jtmproject.classes.SerializeUtils;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Handler;
import android.os.Message;

/**
 * This is the class which the client has method to communicate with the server
 * 
 * @author Javier Tejedor
 * @thanks Google
 */
public class Client implements IClient {

	public static final String START_GAME = "start_game";
	public static final String CANCEL_CONNECTION = "cancel_connection";

	//types of messages for the handle
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_READ = 2;
	public static final int MESSAGE_WRITE = 3;
	public static final int MESSAGE_DEVICE_NAME = 4;
	public static final int MESSAGE_TOAST = 5;

	//keys receive from the service
	public static final String DEVICE_NAME = "device_name";
	public static final String TOAST = "toast";

	private StringBuffer outStringBuffer;
	private BluetoothAdapter bluetoothAdapter = null;
	private ClientService clientService = null;

	private boolean connected = false;

	/**
	 * this stores a copy of Client object 
	 * to share this object between activities  
	 */
	private static Client client;


	/**
	 * constructor
	 * @param activity
	 * @param addressServer
	 * @param mBluetoothAdapter
	 */
	public Client(String addressServer, BluetoothAdapter mBluetoothAdapter){
		this.bluetoothAdapter = mBluetoothAdapter;

		setupCommunication();
		connectDevice(addressServer);
		setStateClient();

	}

	/**
	 * this sets the initial state of the clientService 
	 */
	private void setStateClient() {
		if (clientService != null) {
			if (clientService.getState() == ClientService.STATE_NONE) {
				clientService.start();
			}
		}
	}

	/**
	 * this configures the communication with the server
	 */
	private void setupCommunication() {
		clientService = new ClientService(handler);
		outStringBuffer = new StringBuffer("");
	}

	/**
	 * handler to communicate with the server
	 */
	private final Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {

			case MESSAGE_STATE_CHANGE:
				switch (msg.arg1) {
				case ClientService.STATE_CONNECTED:
					break;
				case ClientService.STATE_CONNECTING:
					break;
				case ClientService.STATE_LISTEN:
				case ClientService.STATE_NONE:
					break;
				}
				break;

			case MESSAGE_WRITE:

				//byte[] writeBuf = (byte[]) msg.obj;
				//String writeMessage = new String(writeBuf);

				break;

			case MESSAGE_READ:

				byte[] readBuf = (byte[]) msg.obj;
				String readMessage = new String(readBuf, 0, msg.arg1);
				if(readMessage.equals(CANCEL_CONNECTION)){
					
					//actions to do when the server has been closed
					
				}else if(readMessage.equals(START_GAME)){
					
					connected = true;
					
				}else{
					
					Object object = SerializeUtils.deserialize(readBuf);

					if(object != null) {
						World world = (World) object;
						PongGame.setWorld(world);
					}
					
				}

			case MESSAGE_DEVICE_NAME:

				break;

			}
		}

	};

	/**
	 * this is to cancel the connection
	 */
	public void cancelConnection(){
		if (clientService != null) {
			clientService.stop();
		} 
		
		if(bluetoothAdapter.isEnabled()) {
			bluetoothAdapter.disable();
		}
	}

	/**
	 * sends a message.
	 * @param message  A string of text to send.
	 */
	public void sendMessage(String message) {

		if (clientService.getState() != ClientService.STATE_CONNECTED) {
			return;
		}

		if (message.length() > 0) {
			byte[] send = message.getBytes();
			clientService.write(send);
			outStringBuffer.setLength(0);

		}
	}

	/**
	 * this is to connect with the server. The parameters is the server's MAC 
	 * @param addressServer
	 */
	private void connectDevice(String addressServer) {
		BluetoothDevice device = 
				bluetoothAdapter.getRemoteDevice(addressServer);
		clientService.connect(device);
	}

	/* (non-Javadoc)
	 * @see com.jtmproject.IClient#isConnected()
	 */
	public boolean isConnected() {
		return connected;
	}

	/* (non-Javadoc)
	 * @see com.jtmproject.IClient#setConnected(boolean)
	 */
	public void setConnected(boolean connected) {
		this.connected = connected;
	}

	/**
	 * returns a object's copy of this class
	 * @return
	 */
	public static Client getClient() {
		return client;
	}

	/**
	 * sets a object's copy of this class
	 * @param client
	 */
	public static void setClient(Client client) {
		Client.client = client;
	}

}
